﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenControls.Core;
using System.Windows.Forms;
using System.Drawing;
using BoneSoft.CSS;

namespace OpenControls
{
    public class ControlCustomizer<TControl,TBase> : IControlCustomizer 
        where TControl : ICustomizableControl
        where TBase : Control
    {
        public ICustomizableControl Control { get; set; }
        public Utils Utils { get; set; }

        public ControlCustomizer()
        {
            this.Utils = new Utils();
        }

        public void LoadMyStyle(ICustomizableControl control)
        {
            if (ControlsConfiguration.LoadedCustomizations.Count > 0)
            {
                foreach (var item in ControlsConfiguration.LoadedCustomizations.Keys)
                {
                    if (item.EndsWith(control.CssFile))
                        control.Style = ControlsConfiguration.LoadedCustomizations[item];
                }
            }
        }

        #region IControlCustomizer Members

        public virtual IStyle GetCustomization()
        {
            throw new NotImplementedException();
        }

        public virtual void PerformCustomization(ICustomizableControl control)
        {
            if (control is Form)
            {
                IControlCustomizer formCustomizer = new FormBaseCustomizer();
                formCustomizer.PerformCustomization(control);
            }
        }

        public virtual void PerformCustomization(ICustomizableControl control, IStyle style)
        {
            throw new NotImplementedException();
        }

        public virtual void ApplyParentCustomization(ICustomizableControl control)
        {
            throw new NotImplementedException();
        }

        public virtual void ApplyParentCustomization()
        {
            throw new NotImplementedException();
        }

        public virtual void CloneCustomization(ICustomizableControl control)
        {
            throw new NotImplementedException();
        }

        public virtual void ApplyColorCustomization(ICustomizableControl control)
        {
            throw new NotImplementedException();
        }

        public virtual void ApplyFontCustomization(ICustomizableControl control)
        {
            float fontSize = 9.75f;
            Font font = null;
            FontFamily fontFamily = null;
            FontStyle fontStyle;
            Declaration declaration;
            bool useBold = false;
            bool useUnderline = false;
            bool useLinethrough = false;
            RuleSet rule = this.Utils.FindRuleSet(control.Style, control.CssClass);


            declaration = rule["font-family"];

            if (declaration != null)
            {
                if (declaration.Expression.Terms.Count > 1)
                    throw new ArgumentException("The font-family declaration shall have only 1 term.");

                fontFamily = new FontFamily(declaration.Expression.Terms[0].Value);
            }

            declaration = rule["font-size"];

            if (declaration != null)
            {
                if (!float.TryParse(declaration.Expression.Terms[0].Value, out fontSize))
                    throw new ArgumentException("The font-size declaration contains invalid values.");
            }

            declaration = rule["font-weight"];

            if (declaration != null)
            {
                if (declaration.Expression.Terms.Count > 1)
                    throw new ArgumentException("The font-weight declaration shall have only 1 term.");

                if ((new string[] { "bold", "bolder" }).Contains<string>(declaration.Expression.Terms[0].Value.ToLower()))
                    useBold = true;
            }

            declaration = rule["text-decoration"];

            if (declaration != null)
            {
                // the System.Windows.Forms.Control class only support the Underline and Strikeout styles

                if (declaration.Expression.Terms.Count == 1)
                {
                    useUnderline = (
                                   declaration.Expression.Terms[0].Value.ToLower() == "underline" ? true : false
                               );
                    useLinethrough = (
                                    declaration.Expression.Terms[0].Value.ToLower() == "line-through" ? true : false
                                );
                }
                else if (declaration.Expression.Terms.Count == 2)
                {
                    useUnderline = (
                                    declaration.Expression.Terms[0].Value.ToLower() == "underline" ? true : false
                                    ||
                                    declaration.Expression.Terms[1].Value.ToLower() == "underline" ? true : false
                                );

                    useLinethrough = (
                                        declaration.Expression.Terms[0].Value.ToLower() == "line-through" ? true : false
                                        ||
                                        declaration.Expression.Terms[1].Value.ToLower() == "line-through" ? true : false
                                    );
                }
                else
                    throw new ArgumentException("The text-decoration declaration shall have only 1 term.");
            }

            /*
             
             *  TODO: The font-variant and text-transform declarations needs to be best understood.
             
             */

            fontStyle = (useBold ? FontStyle.Bold : FontStyle.Regular) |
                        (useUnderline ? FontStyle.Underline : FontStyle.Regular) |
                        (useLinethrough ? FontStyle.Strikeout : FontStyle.Regular);

            font = new Font(fontFamily, fontSize, fontStyle);

            (control as Control).Font = font;
        }

        public virtual void ApplyBorderCustomization(ICustomizableControl control)
        {
        }

        #endregion
    }
}